home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / frasrc19.zip / PRINTER.C < prev    next >
C/C++ Source or Header  |  1995-01-29  |  57KB  |  1,697 lines

  1. /*  Printer.c
  2.  *    Simple screen printing functions for FRACTINT
  3.  *    By Matt Saucier CIS: [72371,3101]      7/2/89
  4.  *    "True-to-the-spirit" of FRACTINT, this code makes few checks that you
  5.  *    have specified a valid resolution for the printer (just in case yours
  6.  *    has more dots/line than the Standard HP and IBM/EPSON,
  7.  *    (eg, Wide Carriage, etc.))
  8.  *
  9.  *    PostScript support by Scott Taylor [72401,410] / (DGWM18A)   10/8/90
  10.  *    For PostScript, use 'printer=PostScript/resolution' where resolution
  11.  *    is ANY NUMBER between 10 and 600. Common values: 300,150,100,75.
  12.  *    Default resolution for PostScript is 150 pixels/inch.
  13.  *    At 200 DPI, a fractal that is 640x480 prints as a 3.2"x2.4" picture.
  14.  *    PostScript printer names:
  15.  *
  16.  *    PostScript/PS            = Portrait printing
  17.  *    PostScriptH/PostScriptL/PSH/PSL = Landscape printing
  18.  *
  19.  *    This code supports printers attached to a LPTx (1-3) parallel port.
  20.  *    It also now supports serial printers AFTER THEY ARE CONFIGURED AND
  21.  *    WORKING WITH THE DOS MODE COMMAND, eg. MODE COM1:9600,n,8,1 (for HP)
  22.  *    (NOW you can also configure the serial port with the comport= command)
  23.  *    Printing calls are made directly to the BIOS for DOS can't handle fast
  24.  *    transfer of data to the HP.  (Or maybe visa-versa, HP can't handle the
  25.  *    slow transfer of data from DOS)
  26.  *
  27.  *    I just added direct port access for COM1 and COM2 **ONLY**. This method
  28.  *    does a little more testing than BIOS, and may work (especially on
  29.  *    serial printer sharing devices) where the old method doesn't. I noticed
  30.  *    maybe a 5% speed increase at 9600 baud. These are selected in the
  31.  *    printer=.../.../31 for COM1 or 32 for COM2.
  32.  *
  33.  *    I also added direct parallel port access for LPT1 and LPT2 **ONLY**.
  34.  *    This toggles the "INIT" line of the parallel port to reset the printer
  35.  *    for each print session. It will also WAIT for a error / out of paper /
  36.  *    not selected condition instead of quitting with an error.
  37.  *
  38.  *    Supported Printers:    Tested Ok:
  39.  *     HP LaserJet
  40.  *        LJ+,LJII         MDS
  41.  *     Toshiba PageLaser     MDS (Set FRACTINT to use HP)
  42.  *     IBM Graphics         MDS
  43.  *     EPSON
  44.  *        Models?         Untested.
  45.  *     IBM LaserPrinter
  46.  *        with PostScript     SWT
  47.  *     HP Plotter         SWT
  48.  *
  49.  *    Future support to include OKI 20 (color) printer, and just about
  50.  *    any printer you request.
  51.  *
  52.  *    Future modifications to include a more flexible, standard interface
  53.  *    with the surrounding program, for easier portability to other
  54.  *    programs.
  55.  *
  56.  * PostScript Styles:
  57.  *  0  Dot
  58.  *  1  Dot*           [Smoother]
  59.  *  2  Inverted Dot
  60.  *  3  Ring
  61.  *  4  Inverted Ring
  62.  *  5  Triangle        [45-45-90]
  63.  *  6  Triangle*       [30-75-75]
  64.  *  7  Grid
  65.  *  8  Diamond
  66.  *  9  Line
  67.  * 10  Microwaves
  68.  * 11  Ellipse
  69.  * 12  RoundBox
  70.  * 13  Custom
  71.  * 14  Star
  72.  * 15  Random
  73.  * 16  Line*           [Not much different]
  74.  *
  75.  *  *  Alternate style
  76.  *
  77.  
  78.  */
  79.  
  80. #include <stdlib.h>
  81.  
  82. #ifndef XFRACT
  83. #include <bios.h>
  84. #include <dos.h>
  85. #include <io.h>
  86. #endif
  87.  
  88. #include <fcntl.h>
  89. #include <sys/types.h>
  90. #include <errno.h>
  91. #include <stdio.h>    /*** for vsprintf prototype ***/
  92.  
  93. #ifndef XFRACT
  94. #include <conio.h>
  95. #include <stdarg.h>
  96. #else
  97. #include <varargs.h>
  98. #endif
  99.  
  100. #include <string.h>
  101. #include <float.h>    /* for pow() */
  102. #include <math.h>    /*  "    "   */
  103. #include "fractint.h"
  104. #include "fractype.h"
  105. #include "prototyp.h"
  106.  
  107. /* macros for near-space-saving purposes */
  108. /* CAE 9211 changed these for BC++ */
  109.  
  110. #define PRINTER_PRINTF1(X) {\
  111.    static FCODE tmp[] = X;\
  112.    Printer_printf(tmp);\
  113. }
  114.  
  115. #define PRINTER_PRINTF2(X,Y) {\
  116.    static FCODE tmp[] = X;\
  117.    Printer_printf(tmp,(Y));\
  118. }
  119. #define PRINTER_PRINTF3(X,Y,Z) {\
  120.    static FCODE tmp[] = X;\
  121.    Printer_printf(tmp,(Y),(Z));\
  122. }
  123. #define PRINTER_PRINTF4(X,Y,Z,W) {\
  124.    static FCODE tmp[] = X;\
  125.    Printer_printf(tmp,(Y),(Z),(W));\
  126. }
  127. #define PRINTER_PRINTF5(X,Y,Z,W,V) {\
  128.    static FCODE tmp[] = X;\
  129.    Printer_printf(tmp,(Y),(Z),(W),(V));\
  130. }
  131. #define PRINTER_PRINTF6(X,Y,Z,W,V,U) {\
  132.    static FCODE tmp[] = X;\
  133.    Printer_printf(tmp,(Y),(Z),(W),(V),(U));\
  134. }
  135. #define PRINTER_PRINTF7(X,Y,Z,W,V,U,T) {\
  136.    static FCODE tmp[] = X;\
  137.    Printer_printf(tmp,(Y),(Z),(W),(V),(U),(T));\
  138. }
  139.  
  140. /********      PROTOTYPES     ********/
  141.  
  142. #ifndef XFRACT
  143. static void Printer_printf(char far *fmt,...);
  144. #else
  145. static void Printer_printf();
  146. #endif
  147. static int  _fastcall printer(int c);
  148. static void _fastcall print_title(int,int,char *);
  149. static void printer_reset(void);
  150. static void rleprolog(int x,int y);
  151. static void _fastcall graphics_init(int,int,char *);
  152.  
  153. /********    GLOBALS       ********/
  154.  
  155. int Printer_Resolution,        /* 75,100,150,300 for HP;           */
  156.                    /* 60,120,240 for IBM;               */
  157.                    /* 90 or 180 for the PaintJet;           */
  158.                    /* 10-600 for PS                */
  159.                    /* 1-20 for Plotter               */
  160.     LPTNumber,               /* ==1,2,3 LPTx; or 11,12,13,14 for COM1-4  */
  161.                    /* 21,22 for direct port access for LPT1-2  */
  162.                    /* 31,32 for direct port access for COM1-2  */
  163.     Printer_Type,               /* ==1 HP,
  164.                       ==2 IBM/EPSON,
  165.                       ==3 Epson color,
  166.                       ==4 HP PaintJet,
  167.                       ==5,6 PostScript,
  168.                       ==7 HP Plotter           */
  169.     Printer_Titleblock,       /* Print info about the fractal?           */
  170.     Printer_Compress,          /* PostScript only - rle encode output       */
  171.     Printer_ColorXlat,          /* PostScript only - invert colors       */
  172.     Printer_SetScreen,          /* PostScript only - reprogram halftone ?    */
  173.     Printer_SFrequency,       /* PostScript only - Halftone Frequency K    */
  174.     Printer_SAngle,           /* PostScript only - Halftone angle     K    */
  175.     Printer_SStyle,           /* PostScript only - Halftone style     K    */
  176.     Printer_RFrequency,       /* PostScript only - Halftone Frequency R    */
  177.     Printer_RAngle,           /* PostScript only - Halftone angle     R    */
  178.     Printer_RStyle,           /* PostScript only - Halftone style     R    */
  179.     Printer_GFrequency,       /* PostScript only - Halftone Frequency G    */
  180.     Printer_GAngle,           /* PostScript only - Halftone angle     G    */
  181.     Printer_GStyle,           /* PostScript only - Halftone style     G    */
  182.     Printer_BFrequency,       /* PostScript only - Halftone Frequency B    */
  183.     Printer_BAngle,           /* PostScript only - Halftone angle     B    */
  184.     Printer_BStyle,           /* PostScript only - Halftone style     B    */
  185.     Print_To_File,          /* Print to file toggle               */
  186.     EPSFileType,          /* EPSFileType -
  187.                            1 = well-behaved,
  188.                            2 = much less behaved,
  189.                            3 = not well behaved       */
  190.     Printer_CRLF,             /* (0) CRLF (1) CR (2) LF                    */
  191.     ColorPS;                  /* (0) B&W  (1) Color                        */
  192. int pj_width;
  193. double ci,ck;
  194.  
  195. static int repeat, item, count, repeatitem, itembuf[128], rlebitsperitem,
  196.     rlebitshift, bitspersample, rleitem, repeatcount, itemsperline, items,
  197.     /* bitsperitem, */ bitshift2;
  198. /*
  199.  *  The tables were copied from Lee Crocker's PGIF program, with
  200.  *  the 8 undithered colors moved to the first 8 table slots.
  201.  *
  202.  *  This file contains various lookup tables used by PJGIF.  Patterns contains
  203.  *  unsigned values representing each of the 330 HP PaintJet colors.  Each color
  204.  *  at 90 DPI is composed of four dots in 8 colors.  Each hex digit of these
  205.  *  unsigned values represents one of the four dots.  Although the PaintJet will
  206.  *  produce these patterns automatically in 90 DPI mode, it is much faster to do
  207.  *  it in software with the PaintJet in 8-color 180 DPI mode.
  208.  *
  209.  *  920501 Hans Wolfgang Schulze converted from printera.asm for xfractint.
  210.  *       (hans@garfield.metal2.polymtl.ca)
  211.  */
  212.  
  213. static UIFCODE pj_patterns [] = {
  214.       0x7777,0x0000,0x1111,0x2222,0x3333,0x4444,0x5555,0x6666,
  215.              0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
  216.       0x0110,0x0120,0x0130,0x0140,0x0150,0x0160,0x0170,0x0220,
  217.       0x0230,0x0240,0x0250,0x0260,0x0270,0x0330,0x0340,0x0350,
  218.       0x0360,0x0370,0x0440,0x0450,0x0460,0x0470,0x0550,0x0560,
  219.       0x0570,0x0660,0x0670,0x0770,0x0111,0x0112,0x0113,0x0114,
  220.       0x0115,0x0116,0x0117,0x2012,0x0123,0x0124,0x0125,0x0126,
  221.       0x0127,0x3013,0x0134,0x0135,0x0136,0x0137,0x4014,0x0145,
  222.       0x0146,0x0147,0x5015,0x0156,0x0157,0x6016,0x0167,0x7017,
  223.       0x0222,0x0223,0x0224,0x0225,0x0226,0x0227,0x3023,0x0234,
  224.       0x0235,0x0236,0x0237,0x4024,0x0245,0x0246,0x0247,0x5025,
  225.       0x0256,0x0257,0x6026,0x0267,0x7027,0x0333,0x0334,0x0335,
  226.       0x0336,0x0337,0x4034,0x0345,0x0346,0x0347,0x5035,0x0356,
  227.       0x0357,0x6036,0x0367,0x7037,0x0444,0x0445,0x0446,0x0447,
  228.       0x5045,0x0456,0x0457,0x6046,0x0467,0x7047,0x0555,0x0556,
  229.       0x0557,0x6056,0x0567,0x7057,0x0666,0x0667,0x7067,0x0777,
  230.              0x1112,0x1113,0x1114,0x1115,0x1116,0x1117,0x2112,
  231.       0x1123,0x2114,0x2115,0x2116,0x2117,0x3113,0x3114,0x3115,
  232.       0x3116,0x3117,0x4114,0x4115,0x4116,0x4117,0x5115,0x5116,
  233.       0x5117,0x6116,0x6117,0x7117,0x1222,0x1223,0x1224,0x1225,
  234.       0x1226,0x1227,0x3123,0x1234,0x1235,0x1236,0x1237,0x4124,
  235.       0x1245,0x1246,0x1247,0x5125,0x1256,0x1257,0x6126,0x1267,
  236.       0x7127,0x1333,0x1334,0x1335,0x1336,0x1337,0x4134,0x1345,
  237.       0x1346,0x1347,0x5135,0x1356,0x1357,0x6136,0x1367,0x7137,
  238.       0x1444,0x1445,0x1446,0x1447,0x5145,0x1456,0x1457,0x6146,
  239.       0x1467,0x7147,0x1555,0x1556,0x1557,0x6156,0x1567,0x7157,
  240.       0x1666,0x1667,0x7167,0x1777,       0x2223,0x2224,0x2225,
  241.       0x2226,0x2227,0x3223,0x3224,0x3225,0x3226,0x3227,0x4224,
  242.       0x4225,0x4226,0x4227,0x5225,0x5226,0x5227,0x6226,0x6227,
  243.       0x7227,0x2333,0x2334,0x2335,0x2336,0x2337,0x4234,0x2345,
  244.       0x2346,0x2347,0x5235,0x2356,0x2357,0x6236,0x2367,0x7237,
  245.       0x2444,0x2445,0x2446,0x2447,0x5245,0x2456,0x2457,0x6246,
  246.       0x2467,0x7247,0x2555,0x2556,0x2557,0x6256,0x2567,0x7257,
  247.       0x2666,0x2667,0x7267,0x2777,       0x3334,0x3335,0x3336,
  248.       0x3337,0x4334,0x4335,0x4336,0x4337,0x5335,0x5336,0x5337,
  249.       0x6336,0x6337,0x7337,0x3444,0x3445,0x3446,0x3447,0x5345,
  250.       0x3456,0x3457,0x6346,0x3467,0x7347,0x3555,0x3556,0x3557,
  251.       0x6356,0x3567,0x7357,0x3666,0x3667,0x7367,0x3777,
  252.       0x4445,0x4446,0x4447,0x5445,0x5446,0x5447,0x6446,0x6447,
  253.       0x7447,0x4555,0x4556,0x4557,0x6456,0x4567,0x7457,0x4666,
  254.       0x4667,0x7467,0x4777,       0x5556,0x5557,0x6556,0x6557,
  255.       0x7557,0x5666,0x5667,0x7567,0x5777,       0x6667,0x7667,
  256.       0x6777};
  257.  
  258. /*
  259.  * The 3 tables below contain the red, green, and blue values (on a scale of
  260.  *  0..255) of each of the 330 PaintJet colors.  These values are based on data
  261.  *  generously provided by HP customer service.
  262.  *       11 <- changed black's value from this, seemed wrong
  263.  *         135 <- changed red's value from this
  264.  *           11 <- changed blue's value from this
  265.  */
  266. static BFCODE  pj_reds[] = {
  267.         229,  2,145,  7,227,  9,136, 5,
  268.              17, 10, 17, 10, 16, 10, 16, 29, 16, 32, 15, 30, 15, 31,  9,
  269.      15, 10, 15,  9, 13, 37, 15, 32, 16, 36, 10, 15,  9, 13, 30, 15,
  270.      31,  8, 13, 38, 62, 26, 68, 26, 63, 26, 68, 16, 35, 16, 33, 16,
  271.      33, 77, 26, 69, 29, 77, 16, 31, 16, 31, 64, 27, 71, 16, 36, 81,
  272.       9, 15, 10, 15,  8, 13, 37, 15, 31, 15, 33, 10, 15,  9, 13, 29,
  273.      15, 28,  8, 12, 28, 98, 28, 79, 32, 94, 16, 34, 17, 35, 73, 30,
  274.      82, 17, 43,101, 11, 15, 10, 13, 29, 15, 27,  9, 13, 25, 65, 27,
  275.      71, 16, 35, 88,  7, 12, 39,110,     54,146, 53,136, 58,144, 29,
  276.      57, 28, 53, 29, 56,159, 54,144, 61,160, 27, 51, 28, 52,135, 55,
  277.     144, 30, 60,159, 14, 23, 15, 22, 14, 21, 64, 30, 58, 32, 64, 15,
  278.      22, 15, 21, 54, 31, 56, 14, 22, 64,185, 59,160, 69,185, 29, 57,
  279.      31, 60,145, 63,162, 33, 71,186, 15, 22, 16, 21, 50, 30, 52, 15,
  280.      21, 54,134, 58,145, 30, 60,161, 15, 22, 69,187,     13,  9, 14,
  281.       6, 11, 31, 14, 27, 12, 27, 10, 14,  9, 12, 24,  9, 23,  6,  9,
  282.      22, 76, 23, 61, 25, 74, 15, 29, 14, 28, 55, 23, 62, 12, 30, 73,
  283.          11, 15, 10, 12, 25, 14, 23,  8, 11, 20, 50, 22, 53, 13, 26, 61,
  284.           5,  8, 21, 71,     71,189, 87,227, 30, 63, 32, 69,164, 76,190,
  285.          37, 89,227, 15, 22, 14, 20, 54, 31, 57, 14, 21, 63,147, 67,163,
  286.          33, 72,191, 13, 24, 94,228,     15, 10, 13, 26, 14, 23, 10, 13,
  287.          20, 50, 23, 50, 15, 26, 52,  8, 11, 23, 65,     60,147, 32, 67,
  288.         166, 14, 24, 77,194,      8, 32, 97};
  289.  
  290. /*
  291.  *                   11 <- changed black's value from this, seemed wrong
  292.  *                           65 <- changed green from this
  293.  */
  294.  
  295. static BFCODE pj_greens[] = {
  296.         224,  2, 20, 72,211, 10, 11, 55,
  297.              12, 15, 19, 11, 11, 14, 17, 14, 18, 22, 12, 13, 16, 19, 24,
  298.          29, 16, 17, 23, 27, 41, 17, 22, 29, 39, 11, 10, 14, 14, 11, 14,
  299.          17, 21, 25, 40, 16, 21, 28, 14, 16, 19, 25, 28, 37, 18, 20, 26,
  300.          33, 48, 20, 26, 33, 46, 13, 12, 16, 18, 14, 18, 22, 24, 30, 42,
  301.          40, 49, 25, 27, 39, 50, 69, 27, 33, 48, 66, 17, 17, 24, 27, 19,
  302.          28, 35, 38, 48, 68,100, 32, 46, 65, 98, 18, 22, 29, 36, 27, 39,
  303.          54, 49, 71,105, 11, 10, 14, 12, 10, 14, 13, 20, 20, 25, 11, 15,
  304.          18, 22, 29, 49, 36, 46, 69,111,     23, 31, 16, 19, 22, 28, 30,
  305.          37, 20, 22, 28, 34, 54, 22, 29, 36, 53, 14, 15, 17, 19, 17, 19,
  306.          26, 25, 32, 46, 43, 50, 27, 28, 41, 49, 68, 29, 37, 51, 68, 19,
  307.          19, 25, 28, 22, 30, 36, 40, 47, 66,104, 35, 51, 68,105, 20, 24,
  308.          31, 37, 30, 38, 56, 50, 69,103, 13, 12, 15, 14, 13, 15, 16, 21,
  309.          21, 26, 14, 16, 22, 23, 28, 44, 35, 42, 62,102,     78, 40, 44,
  310.          65, 78, 98, 43, 53, 76, 99, 26, 27, 36, 40, 29, 43, 50, 63, 75,
  311.          99,136, 49, 69, 98,142, 28, 32, 42, 51, 39, 52, 73, 77,103,145,
  312.          17, 17, 21, 21, 18, 22, 24, 34, 37, 43, 19, 23, 30, 40, 48, 69,
  313.          62, 76,101,147,     72,113,145,218, 33, 42, 52, 71, 61, 77,116,
  314.         105,148,221, 18, 17, 21, 23, 21, 26, 30, 37, 43, 64, 30, 35, 48,
  315.          50, 69,115, 77, 99,149,224,     10, 13, 11, 10, 12, 11, 17, 16,
  316.          15,  9, 11, 12, 17, 17, 22, 26, 27, 36, 61,     14, 18, 21, 26,
  317.          48, 34, 41, 68,115,     69, 99,149};
  318.  
  319. /*                    15 <- changed black's value from this, seemed wrong
  320.  *                           56 <- changed green from this
  321.  *                                          163 <- changed cyan from this
  322.  */
  323. static BFCODE pj_blues[] = {
  324.         216,  2, 34, 48, 33, 73, 64,168,
  325.              18, 19, 18, 20, 19, 22, 21, 22, 24, 22, 26, 24, 27, 24, 27,
  326.          24, 29, 27, 31, 29, 22, 27, 25, 30, 28, 31, 29, 33, 33, 28, 32,
  327.          32, 41, 40, 46, 28, 32, 28, 34, 30, 36, 31, 35, 32, 38, 34, 41,
  328.          35, 27, 35, 31, 39, 34, 40, 37, 44, 40, 34, 42, 37, 49, 47, 45,
  329.          40, 36, 43, 40, 47, 43, 33, 40, 36, 45, 41, 44, 41, 49, 46, 40,
  330.          49, 45, 58, 56, 58, 30, 38, 34, 44, 40, 42, 39, 49, 46, 38, 49,
  331.          46, 59, 62, 67, 49, 46, 55, 52, 44, 55, 52, 64, 64, 66, 43, 55,
  332.          53, 66, 70, 78, 87, 91,101,115,     39, 34, 42, 37, 43, 36, 45,
  333.          38, 47, 42, 49, 43, 34, 41, 36, 44, 38, 49, 45, 52, 46, 40, 47,
  334.          42, 56, 51, 45, 49, 45, 52, 48, 56, 50, 40, 47, 44, 52, 47, 54,
  335.          51, 59, 55, 47, 58, 50, 66, 60, 56, 34, 44, 38, 48, 42, 52, 47,
  336.          56, 50, 42, 51, 46, 64, 59, 57, 60, 56, 64, 61, 52, 61, 57, 72,
  337.          67, 64, 48, 58, 53, 69, 65, 65, 87, 83, 87, 94,     53, 59, 55,
  338.          64, 60, 46, 53, 49, 59, 54, 60, 56, 65, 62, 53, 62, 58, 76, 71,
  339.          68, 41, 50, 45, 56, 51, 58, 53, 63, 59, 49, 60, 56, 74, 71, 71,
  340.          66, 63, 73, 70, 60, 69, 67, 84, 81, 79, 55, 67, 64, 84, 81, 83,
  341.         104,104,106,116,     32, 40, 53, 48, 54, 50, 61, 57, 46, 59, 56,
  342.          76, 75, 80, 64, 59, 70, 67, 57, 69, 65, 83, 81, 85, 54, 68, 66,
  343.          86, 88, 96,110,114,125,137,     71, 81, 78, 68, 77, 76, 93, 92,
  344.          90, 65, 77, 75, 92, 93, 96,117,119,126,138,     78, 79, 98,102,
  345.         110,124,131,143,157,    173,185,200};
  346.     
  347. static void putitem(void);
  348. static void rleputxelval(int);
  349. static void rleflush(void);
  350. static void rleputrest(void);
  351.  
  352. static int LPTn;           /* printer number we're gonna use */
  353.  
  354. static FILE *PRFILE;
  355.  
  356. #define TONES 17           /* Number of PostScript halftone styles */
  357.  
  358. #if 1
  359. static FCODE ht00[] = {"D mul exch D mul add 1 exch sub"};
  360. static FCODE ht01[] = {"abs exch abs 2 copy add 1 gt {1 sub D mul exch 1 sub D mul add 1 sub} {D mul exch D mul add 1 exch sub} ifelse"};
  361. static FCODE ht02[] = {"D mul exch D mul add 1 sub"};
  362. static FCODE ht03[] = {"D mul exch D mul add 0.6 exch sub abs -0.5 mul"};
  363. static FCODE ht04[] = {"D mul exch D mul add 0.6 exch sub abs 0.5 mul"};
  364. static FCODE ht05[] = {"add 2 div"};
  365. static FCODE ht06[] = {"2 exch sub exch abs 2 mul sub 3 div"};
  366. static FCODE ht07[] = {"2 copy abs exch abs gt {exch} if pop 2 mul 1 exch sub 3.5 div"};
  367. static FCODE ht08[] = {"abs exch abs add 1 exch sub"};
  368. static FCODE ht09[] = {"pop"};
  369. static FCODE ht10[] = {"/wy exch def 180 mul cos 2 div wy D D D mul mul sub mul wy add 180 mul cos"};
  370. static FCODE ht11[] = {"D 5 mul 8 div mul exch D mul exch add sqrt 1 exch sub"};
  371. static FCODE ht12[] = {"D mul D mul exch D mul D mul add 1 exch sub"};
  372. static FCODE ht13[] = {"D mul exch D mul add sqrt 1 exch sub"};
  373. static FCODE ht14[] = {"abs exch abs 2 copy gt {exch} if 1 sub D 0 eq {0.01 add} if atan 360 div"};
  374. static FCODE ht15[] = {"pop pop rand 1 add 10240 mod 5120 div 1 exch sub"};
  375. static FCODE ht16[] = {"pop abs 2 mul 1 exch sub"};
  376. #endif
  377.  
  378. static FCODE *HalfTone[TONES]=  {ht00,ht01,ht02,ht03,ht04,ht05,ht06,ht07,
  379.     ht08,ht09,ht10,ht11,ht12,ht13,ht14,ht15,ht16};
  380.  
  381. #if 0
  382.              "D mul exch D mul add 1 exch sub",
  383.              "abs exch abs 2 copy add 1 gt {1 sub D mul exch 1 sub D mul add 1 sub} {D mul exch D mul add 1 exch sub} ifelse",
  384.              "D mul exch D mul add 1 sub",
  385.              "D mul exch D mul add 0.6 exch sub abs -0.5 mul",
  386.              "D mul exch D mul add 0.6 exch sub abs 0.5 mul",
  387.              "add 2 div",
  388.              "2 exch sub exch abs 2 mul sub 3 div",
  389.              "2 copy abs exch abs gt {exch} if pop 2 mul 1 exch sub 3.5 div",
  390.              "abs exch abs add 1 exch sub",
  391.              "pop",
  392.              "/wy exch def 180 mul cos 2 div wy D D D mul mul sub mul wy add 180 mul cos",
  393.              "D 5 mul 8 div mul exch D mul exch add sqrt 1 exch sub",
  394.              "D mul D mul exch D mul D mul add 1 exch sub",
  395.              "D mul exch D mul add sqrt 1 exch sub",
  396.              "abs exch abs 2 copy gt {exch} if 1 sub D 0 eq {0.01 add} if atan 360 div",
  397.              "pop pop rand 1 add 10240 mod 5120 div 1 exch sub",
  398.              "pop abs 2 mul 1 exch sub"
  399.             };
  400. #endif
  401.  
  402. #ifdef __BORLANDC__
  403. #if(__BORLANDC__ > 2)
  404.    #pragma warn -eff
  405. #endif
  406. #endif
  407.  
  408. static char EndOfLine[3];
  409.  
  410. /* workaround for the old illicit decflaration of dstack */
  411.  
  412. typedef int (*TRIPLE)[2][3][400];
  413. #define triple   (*((TRIPLE)dstack))
  414.  
  415. void 
  416. Print_Screen (void)
  417. {
  418.     int y,j;
  419.     char buff[192];        /* buffer for 192 sets of pixels  */
  420.                 /* This is very large so that we can*/
  421.                 /* get reasonable times printing  */
  422.                 /* from modes like MAXPIXELSxMAXPIXELS disk-*/
  423.                 /* video.  When this was 24, a MAXPIXELS*/
  424.                 /* by MAXPIXELS pic took over 2 hours to*/
  425.                 /* print.  It takes about 15 min now*/
  426.     int BuffSiz;        /* how much of buff[] we'll use   */
  427.     char far *es;        /* pointer to extraseg for buffer */
  428.     int i,x,k,            /* more indices           */
  429.     imax,            /* maximum i value (ydots/8)      */
  430.     res,            /* resolution we're gonna' use    */
  431.     high,            /* if LPTn>10 COM == com port to use*/
  432.     low,            /* misc               */
  433.                 /************************************/
  434.     ptrid;            /* Printer Id code.          */
  435.                 /* Currently, the following are   */
  436.                 /* assigned:              */
  437.                 /*          1. HPLJ (all)      */
  438.                 /*         Toshiba PageLaser*/
  439.                 /*          2. IBM Graphics      */
  440.                 /*          3. Color Printer      */
  441.                 /*          4. HP PaintJet      */
  442.                 /*          5. PostScript      */
  443.                 /************************************/
  444.     int pj_color_ptr[256];    /* Paintjet color translation */
  445.  
  446.                 /********   SETUP VARIABLES  ********/
  447.     memset(buff,0,192);
  448.     i = 0;
  449.     
  450.     EndOfLine[0]=(char)(((Printer_CRLF==1) || (Printer_CRLF==0)) ? 0x0D : 0x0A);
  451.     EndOfLine[1]=(char)((Printer_CRLF==0) ? 0x0A : 0x00);
  452.     EndOfLine[2]=0x00;
  453.  
  454.     if (Print_To_File>0)
  455.       {
  456.       while ((PRFILE = fopen(PrintName,"r")) != NULL) {
  457.      j = fgetc(PRFILE);
  458.      fclose(PRFILE);
  459.      if (j == EOF) break;
  460.      updatesavename((char *)PrintName);
  461.      }
  462.       if ((PRFILE = fopen(PrintName,"wb")) == NULL) Print_To_File = 0;
  463.       }
  464.  
  465. #ifdef XFRACT
  466.       putstring(3,0,0,"Printing to:");
  467.       putstring(4,0,0,PrintName);
  468.       putstring(5,0,0,"               ");
  469. #endif
  470.  
  471.     es=MK_FP(extraseg,0);
  472.  
  473.     LPTn=LPTNumber-1;
  474.     if (((LPTn>2)&&(LPTn<10))||
  475.     ((LPTn>13)&&(LPTn<20))||
  476.     ((LPTn>21)&&(LPTn<30))||
  477.     (LPTn<0)||(LPTn>31)) LPTn=0;   /* default of LPT1 (==0)      */
  478.     ptrid=Printer_Type;
  479.     if ((ptrid<1)||(ptrid>7)) ptrid=2; /* default of IBM/EPSON         */
  480.     res=Printer_Resolution;
  481. #ifndef XFRACT
  482.     if ((LPTn==20)||(LPTn==21))
  483.     {
  484.     k = (inp((LPTn==20) ? 0x37A : 0x27A)) & 0xF7;
  485.     outp((LPTn==20) ? 0x37A : 0x27A,k);
  486.     k = k & 0xFB;
  487.     outp((LPTn==20) ? 0x37A : 0x27A,k);
  488.     k = k | 0x0C;
  489.     outp((LPTn==20) ? 0x37A : 0x27A,k);
  490.     }
  491.     if ((LPTn==30)||(LPTn==31))
  492.     {
  493.     outp((LPTn==30) ? 0x3F9 : 0x2F9,0x00);
  494.     outp((LPTn==30) ? 0x3FC : 0x2FC,0x00);
  495.     outp((LPTn==30) ? 0x3FC : 0x2FC,0x03);
  496.     }
  497. #endif
  498.  
  499.     switch (ptrid) {
  500.  
  501.     case 1:
  502.         if (res<75) res=75;
  503.         if ( (res<= 75)&&(ydots> 600)) res=100;
  504.         if ( (res<=100)&&(ydots> 800)) res=150;
  505.         if (((res<=150)&&(ydots>1200))||(res>300)) res=300;
  506.         break;
  507.  
  508.     case 2:
  509.     case 3:
  510.         if (res<60) res=60;
  511.         if ((res<=60)&&(ydots>480)) res=120;
  512.         if (((res<=120)&&(ydots>960))||(res>240)) res=240;
  513.         break;
  514.  
  515.     case 4: /****** PaintJet  *****/
  516.         {
  517. #ifndef XFRACT
  518.         /* Pieter Branderhorst:
  519.            My apologies if the numbers and approach here seem to be
  520.            picked out of a hat.  They were.  They happen to result in
  521.            a tolerable mapping of screen colors to printer colors on
  522.            my machine.  There are two sources of error in getting colors
  523.            to come out right.
  524.            1) Must match some dacbox values to the 330 PaintJet dithered
  525.           colors so that they look the same.  For this we use HP's
  526.           color values in printera.asm and modify by gamma separately
  527.           for each of red/green/blue.  This mapping is ok if the
  528.           preview shown on screen is a fairly close match to what
  529.           gets printed. The defaults are what work for me.
  530.            2) Must find nearest color in HP palette to each color in
  531.           current image. For this we use Lee Crocker's least sum of
  532.           differences squared approach, modified to spread the
  533.           values using gamma 1.7.  This mods was arrived at by
  534.           trial and error, just because it improves the mapping.
  535.            */
  536.         long ldist;
  537.         int r,g,b;
  538.         double gamma_val,gammadiv;
  539.         BYTE convert[256];
  540.         BYTE scale[64];
  541.  
  542.         BYTE far *table_ptr = NULL;
  543.         res = (res < 150) ? 90 : 180;   /* 90 or 180 dpi */
  544.         if (Printer_SetScreen == 0) {
  545.         Printer_SFrequency = 21;  /* default red gamma */
  546.         Printer_SAngle       = 19;  /*       green gamma */
  547.         Printer_SStyle       = 16;  /*        blue gamma */
  548.         }
  549.         /* Convert the values in printera.asm.  We might do this just   */
  550.         /* once per run, but we'd need separate memory for that - can't */
  551.         /* just convert table in-place cause it could be in an overlay, */
  552.         /* might be paged out and then back in in original form.  Also, */
  553.         /* user might change gammas with a .par file entry mid-run.     */
  554.         for (j = 0; j < 3; ++j) {
  555.         switch (j) {
  556.             case 0: table_ptr = pj_reds;
  557.                 i = Printer_SFrequency;
  558.                 break;
  559.             case 1: table_ptr = pj_greens;
  560.                 i = Printer_SAngle;
  561.                 break;
  562.             case 2: table_ptr = pj_blues;
  563.                 i = Printer_SStyle;
  564.             }
  565.         gamma_val = 10.0 / i;
  566.         gammadiv = pow(255,gamma_val) / 255;
  567.         for (i = 0; i < 256; ++i) { /* build gamma conversion table */
  568.             if ((i & 15) == 15)
  569.             thinking(1,"Calculating color translation");
  570.             convert[i] = (BYTE)((pow((double)i,gamma_val) / gammadiv) + 0.5);
  571.             }
  572.         for (i = 0; i < 330; ++i) {
  573.             k = convert[table_ptr[i]];
  574.             if (k > 252) k = 252;
  575.             triple[0][j][i] = (k + 2) >> 2;
  576.         }
  577.         }
  578.         /* build comparison lookup table */
  579.         gamma_val = 1.7;
  580.         gammadiv = pow(63,gamma_val) / 63;
  581.         for (i = 0; i < 64; ++i) {
  582.            if ((j = (int)((pow((double)i,gamma_val) / gammadiv) * 4 + 0.5)) < i)
  583.           j = i;
  584.            scale[i] = (char)j;
  585.         }
  586.         for (i = 0; i < 3; ++i) /* convert values via lookup */
  587.         for (j = 0; j < 330; ++j)
  588.             triple[1][i][j] = scale[triple[0][i][j]];
  589.         /* Following code and the later code which writes to Paintjet    */
  590.         /* using pj_patterns was adapted from Lee Crocker's PGIF program */
  591.         for (i = 0; i < colors; ++i) { /* find nearest match colors */
  592.         r = scale[dacbox[i][0]];
  593.         g = scale[dacbox[i][1]];
  594.         b = scale[dacbox[i][2]];
  595.         ldist = 9999999L;
  596.         /* check variance vs each PaintJet color */
  597.         /* if high-res 8 color mode, consider only 1st 8 colors */
  598.         j = (res == 90) ? 330 : 8;
  599.         while (--j >= 0) {
  600.             long dist;
  601.             dist  = (unsigned)(r-triple[1][0][j]) * (r-triple[1][0][j]);
  602.             dist += (unsigned)(g-triple[1][1][j]) * (g-triple[1][1][j]);
  603.             dist += (unsigned)(b-triple[1][2][j]) * (b-triple[1][2][j]);
  604.             if (dist < ldist) {
  605.             ldist = dist;
  606.             k = j;
  607.             }
  608.         }
  609.         pj_color_ptr[i] = k; /* remember best fit */
  610.         }
  611.         thinking(0,NULL);
  612.     /*  if (debugflag == 900 || debugflag == 902) {
  613.         color_test();
  614.         return;
  615.         }  */
  616.         if (dotmode != 11) { /* preview */
  617.             static char far msg[] = {"Preview. Enter=go, Esc=cancel, k=keep"};
  618.         memcpy(triple[1],dacbox,768);
  619.         for (i = 0; i < colors; ++i)
  620.             for (j = 0; j < 3; ++j)
  621.             dacbox[i][j] = (BYTE)triple[0][j][pj_color_ptr[i]];
  622.         spindac(0,1);
  623.         texttempmsg(msg);
  624.         i = getakeynohelp();
  625.         if (i == 'K' || i == 'k') {
  626.             return;
  627.         }
  628.         memcpy(dacbox,triple[1],768);
  629.         spindac(0,1);
  630.         if (i == 0x1B) {
  631.             return;
  632.         }
  633.         }
  634.         break;
  635. #endif
  636.         }
  637.  
  638.     case 5:
  639.     case 6: /***** PostScript *****/
  640.         if ( res < 10 && res != 0 ) res = 10; /* PostScript scales... */
  641.         if ( res > 600 ) res = 600; /* it can handle any range! */
  642.         if ((Printer_SStyle < 0) || (Printer_SStyle >= TONES))
  643.         Printer_SStyle = 0;
  644.         break;
  645.     }
  646.  
  647.     /*****  Set up buffer size for immediate user gratification *****/
  648.     /*****    AKA, if we don't have to, don't buffer the data   *****/
  649.     BuffSiz=8;
  650.     if (xdots>1024) BuffSiz=192;
  651.  
  652.     /*****   Initialize printer  *****/
  653.     if (Print_To_File < 1) {
  654.     printer_reset();
  655.     /* wait a bit, some printers need time after reset */
  656.     delay((ptrid == 4) ? 2000 : 500);
  657.     }
  658.  
  659.     /******  INITIALIZE GRAPHICS MODES    ******/
  660.  
  661.     graphics_init(ptrid,res,EndOfLine);
  662.  
  663.     if (keypressed()) {     /* one last chance before we start...*/
  664.     return;
  665.     }
  666.  
  667.     memset(buff,0,192);
  668.  
  669.                 /*****    Get And Print Screen **** */
  670.     switch (ptrid) {
  671.  
  672.     case 1:                /* HP LaserJet (et al)         */
  673.         imax=(ydots/8)-1;
  674.         for (x=0;((x<xdots)&&(!keypressed()));x+=BuffSiz) {
  675.         for (i=imax;((i>=0)&&(!keypressed()));i--) {
  676.             for (y=7;((y>=0)&&(!keypressed()));y--) {
  677.             for (j=0;j<BuffSiz;j++) {
  678.                 if ((x+j)<xdots) {
  679.                 buff[j]<<=1;
  680.                 buff[j]=(char)(buff[j]+(char)(getcolor(x+j,i*8+y)&1));
  681.                 }
  682.                 }
  683.             }
  684.             for (j=0;j<BuffSiz;j++) {
  685.             *(es+j+BuffSiz*i)=buff[j];
  686.             buff[j]=0;
  687.             }
  688.             }
  689.         for (j=0;((j<BuffSiz)&&(!keypressed()));j++) {
  690.             if ((x+j)<xdots) {
  691.             PRINTER_PRINTF2("\033*b%iW",imax+1);
  692.             for (i=imax;((i>=0)&&(!keypressed()));i--) {
  693.                 printer(*(es+j+BuffSiz*i));
  694.                 }
  695.             }
  696.             }
  697.         }
  698.         if (!keypressed()) PRINTER_PRINTF1("\033*rB\014");
  699.         break;
  700.  
  701.     case 2:                /* IBM Graphics/Epson         */
  702.         for (x=0;((x<xdots)&&(!keypressed()));x+=8) {
  703.         switch (res) {
  704.             case 60:  Printer_printf("\033K"); break;
  705.             case 120: Printer_printf("\033L"); break;
  706.             case 240: Printer_printf("\033Z"); break;
  707.             }
  708.         high=ydots/256;
  709.         low=ydots-(high*256);
  710.         printer(low);
  711.         printer(high);
  712.         for (y=ydots-1;(y>=0);y--) {
  713.             buff[0]=0;
  714.             for (i=0;i<8;i++) {
  715.             buff[0]<<=1;
  716.             buff[0]=(char)(buff[0]+(char)(getcolor(x+i,y)&1));
  717.             }
  718.             printer(buff[0]);
  719.             }
  720.         if (keypressed()) break;
  721.         Printer_printf(EndOfLine);
  722.         }
  723.         if (!keypressed()) printer(12);
  724.         break;
  725.  
  726.     case 3:                /* IBM Graphics/Epson Color    */
  727.         high=ydots/256;
  728.         low=ydots%256;
  729.         for (x=0;((x<xdots)&&(!keypressed()));x+=8)
  730.         {
  731.         for (k=0; k<8; k++)  /* colors */
  732.             {
  733.             Printer_printf("\033r%d",k); /* set printer color */
  734.             switch (res)
  735.             {
  736.             case 60:  Printer_printf("\033K"); break;
  737.             case 120: Printer_printf("\033L"); break;
  738.             case 240: Printer_printf("\033Z"); break;
  739.             }
  740.             printer(low);
  741.             printer(high);
  742.             for (y=ydots-1;y>=0;y--)
  743.             {
  744.             buff[0]=0;
  745.             for (i=0;i<8;i++)
  746.                 {
  747.                 buff[0]<<=1;
  748.                 if ((getcolor(x+i,y)%8)==k)
  749.                 buff[0]++;
  750.                 }
  751.             printer(buff[0]);
  752.             }
  753.             if (Printer_CRLF<2) printer(13);
  754.             }
  755.         if ((Printer_CRLF==0) || (Printer_CRLF==2)) printer(10);
  756.         }
  757.         printer(12);
  758.         printer(12);
  759.         printer_reset();
  760.         break;
  761.  
  762.     case 4:               /* HP PaintJet       */
  763.         {
  764.         unsigned int fetchrows,fetched;
  765.         BYTE far *pixels = NULL, far *nextpixel = NULL;
  766.         /* for reasonable speed when using disk video, try to fetch
  767.            and store the info for 8 columns at a time instead of
  768.            doing getcolor calls down each column in separate passes */
  769.         fetchrows = 16;
  770.         for(;;) {
  771.         if ((pixels = farmemalloc((long)(fetchrows)*ydots)) != NULL) 
  772.            break;
  773.         if ((fetchrows >>= 1) == 0) {
  774.             static char far msg[]={"insufficient memory"};
  775.             stopmsg(0,msg);
  776.             break;
  777.         }
  778.         }
  779.         if (!pixels) break;
  780.         fetched = 0;
  781.         for (x = 0; (x < xdots && !keypressed()); ++x) {
  782.         if (fetched == 0) {
  783.             if ((fetched = xdots-x) > fetchrows)
  784.             fetched = fetchrows;
  785.             for (y = ydots-1; y >= 0; --y) {
  786.             if (debugflag == 602) /* flip image */
  787.                 nextpixel = pixels + y;
  788.             else              /* reverse order for unflipped */
  789.                 nextpixel = pixels + ydots-1 - y;
  790.             for (i = 0; i < (int)fetched; ++i) {
  791.                 *nextpixel = (BYTE)getcolor(x+i,y);
  792.                 nextpixel += ydots;
  793.             }
  794.             }
  795.             nextpixel = pixels;
  796.         }
  797.         --fetched;
  798.         if (res == 180) { /* high-res 8 color mode */
  799.             int offset;
  800.             BYTE bitmask;
  801.             offset = -1;
  802.             bitmask = 0;
  803.             for (y = ydots - 1; y >= 0; --y) {
  804.             BYTE color;
  805.             if ((bitmask >>= 1) == 0) {
  806.                 ++offset;
  807.                 triple[0][0][offset] = triple[0][1][offset]
  808.                          = triple[0][2][offset] = 0;
  809.                 bitmask = 0x80;
  810.             }
  811.             /* translate 01234567 to 70123456 */
  812.             color = (BYTE)(pj_color_ptr[*(nextpixel++)] - 1);
  813.             if ((color & 1)) triple[0][0][offset] += bitmask;
  814.             if ((color & 2)) triple[0][1][offset] += bitmask;
  815.             if ((color & 4)) triple[0][2][offset] += bitmask;
  816.             }
  817.         }
  818.         else { /* 90 dpi, build 2 lines, 2 dots per pixel */
  819.             int bitct,offset;
  820.             bitct = offset = 0;
  821.             for (y = ydots - 1; y >= 0; --y) {
  822.             unsigned int color;
  823.             color = pj_patterns[pj_color_ptr[*(nextpixel++)]];
  824.             for (i = 0; i < 3; ++i) {
  825.                 BYTE *bufptr;
  826.                 bufptr = (BYTE *)&triple[0][i][offset];
  827.                 *bufptr <<= 2;
  828.                 if ((color & 0x1000)) *bufptr += 2;
  829.                 if ((color & 0x0100)) ++*bufptr;
  830.                 bufptr = (BYTE *)&triple[1][i][offset];
  831.                 *bufptr <<= 2;
  832.                 if ((color & 0x0010)) *bufptr += 2;
  833.                 if ((color & 0x0001)) ++*bufptr;
  834.                 color >>= 1;
  835.             }
  836.             if (++bitct == 4) {
  837.                 bitct = 0;
  838.                 ++offset;
  839.             }
  840.             }
  841.         }
  842.         for (i = 0; i < ((res == 90) ? 2 : 1); ++i) {
  843.             for (j = 0; j < 3; ++j) {
  844.             BYTE *bufptr,*bufend;
  845.             Printer_printf((j < 2) ? "\033*b%dV" : "\033*b%dW",
  846.                        pj_width);
  847.             bufend = pj_width + (bufptr = (BYTE *)(triple[i][j]));
  848.             do {
  849.                 while (printer(*bufptr)) { }
  850.             } while (++bufptr < bufend);
  851.             }
  852.         }
  853.         }
  854.         PRINTER_PRINTF1("\033*r0B"); /* end raster graphics */
  855.         if (!keypressed())
  856.            if (debugflag != 600)
  857.           printer(12); /* form feed */
  858.            else
  859.           Printer_printf("\n\n");
  860.         farmemfree(pixels);
  861.         break;
  862.         }
  863.  
  864.     case 5:
  865.     case 6:     /***** PostScript Portrait & Landscape *****/
  866.         {
  867.         char convert[513];
  868.         if (!ColorPS)
  869.           for (i=0; i<256; ++i)
  870.                 if (Printer_Compress) {
  871.                     convert[i] = (char)((.3*255./63. * (double)dacbox[i][0])+
  872.                                         (.59*255./63. * (double)dacbox[i][1])+
  873.                                         (.11*255./63. * (double)dacbox[i][2]));
  874.                 } else
  875.                 {
  876.                     sprintf(&convert[2*i], "%02X",
  877.                               (int)((.3*255./63. * (double)dacbox[i][0])+
  878.                                     (.59*255./63. * (double)dacbox[i][1])+
  879.                                     (.11*255./63. * (double)dacbox[i][2])));
  880.                 }
  881.         i=0;
  882.         j=0;
  883.         for (y=0;((y<ydots)&&(!keypressed()));y++)
  884.         {   unsigned char bit8 = 0;
  885.         if (Printer_Compress) {
  886.             if (ColorPS) {
  887.             for (x=0;x<xdots;x++) {
  888.                 k=getcolor(x,y);
  889.                 rleputxelval((int)dacbox[k][0]<<2);
  890.             }
  891.             rleflush();
  892.             for (x=0;x<xdots;x++) {
  893.                 k=getcolor(x,y);
  894.                 rleputxelval((int)dacbox[k][1]<<2);
  895.             }
  896.             rleflush();
  897.             for (x=0;x<xdots;x++) {
  898.                 k=getcolor(x,y);
  899.                 rleputxelval((int)dacbox[k][2]<<2);
  900.             }
  901.             rleflush();
  902.              } else {
  903.             if (Printer_ColorXlat==-2 || Printer_ColorXlat==2) {
  904.                for (x=0;x<xdots;x++) {
  905.                   k=getcolor(x,y);
  906.                               k=getcolor(x,y) & 1;
  907.                   if (x % 8 == 0) {
  908.                  if (x) rleputxelval((int)bit8);
  909.                                  if (k) bit8 = 1; else bit8 = 0;
  910.                   }
  911.                   else
  912.                                  bit8 = (unsigned char)((bit8 << 1) + ((k) ? 1 : 0));
  913.                }
  914.                if (xdots % 8) bit8 <<= (8 - (xdots % 8));
  915.                        rleputxelval((int)bit8);
  916.                rleflush();
  917.             } else {
  918.                for (x=0;x<xdots;x++) {
  919.                   k=getcolor(x,y);
  920.                   rleputxelval((int)(unsigned char)convert[k]);
  921.                }
  922.                  rleflush();
  923.             }
  924.              }
  925.         } else
  926.         {
  927.             for (x=0;x<xdots;x++)
  928.             {
  929.             k=getcolor(x,y);
  930.             if (ColorPS)
  931.               {
  932.               sprintf(&buff[i], "%02X%02X%02X", dacbox[k][0]<<2,
  933.                                 dacbox[k][1]<<2,
  934.                                 dacbox[k][2]<<2);
  935.               i+=6;
  936.               }
  937.             else
  938.               {
  939.               k*=2;
  940.               buff[i++]=convert[k];
  941.               buff[i++]=convert[k+1];
  942.               }
  943.             if (i>=64)
  944.             {
  945.                 strcpy(&buff[i],"  ");
  946.                 Printer_printf("%s%s",buff,EndOfLine);
  947.                 i=0;
  948.                 j++;
  949.                 if (j>9)
  950.                 {
  951.                 j=0;
  952.                 Printer_printf(EndOfLine);
  953.                 }
  954.             }
  955.             }
  956.         }
  957.         }
  958.         if (Printer_Compress) {
  959.         rleputrest();
  960.         } else {
  961.         strcpy(&buff[i],"  ");
  962.         Printer_printf("%s%s",buff,EndOfLine);
  963.         i=0;
  964.         j++;
  965.         if (j>9)
  966.         {
  967.             j=0;
  968.             Printer_printf(EndOfLine);
  969.         }
  970.         }
  971.         if ( (EPSFileType > 0) && (EPSFileType <3) )
  972.         {
  973.         PRINTER_PRINTF4("%s%%%%Trailer%sEPSFsave restore%s",EndOfLine,
  974.             EndOfLine,EndOfLine);
  975.             }
  976.         else
  977.             {
  978. #ifndef XFRACT
  979.         PRINTER_PRINTF4("%sshowpage%s%c",EndOfLine,EndOfLine,4);
  980. #else
  981.         PRINTER_PRINTF3("%sshowpage%s",EndOfLine,EndOfLine);
  982. #endif
  983.             }
  984.         break;
  985.         }
  986.  
  987.     case 7: /* HP Plotter */
  988.         {
  989.         double parm1=0,parm2=0;
  990.         for (i=0;i<3;i++)
  991.         {
  992.           PRINTER_PRINTF4("%sSP %d;%s\0",EndOfLine,(i+1),EndOfLine);
  993.           for (y=0;(y<ydots)&&(!keypressed());y++)
  994.           {
  995.         for (x=0;x<xdots;x++)
  996.         {
  997.           j=dacbox[getcolor(x,y)][i];
  998.           if (j>0)
  999.           {
  1000.             switch(Printer_SStyle)
  1001.             {
  1002.               case 0:
  1003.             ci=0.004582144*(double)j;
  1004.             ck= -.007936057*(double)j;
  1005.             parm1 = (double)x+.5+ci+(((double)i-1.0)/3);
  1006.             parm2 = (double)y+.5+ck;
  1007.             break;
  1008.               case 1:
  1009.             ci= -.004582144*(double)j+(((double)i+1.0)/8.0);
  1010.             ck= -.007936057*(double)j;
  1011.             parm1 = (double)x+.5+ci;
  1012.             parm2 = (double)y+.5+ck;
  1013.             break;
  1014.               case 2:
  1015.             ci= -.0078125*(double)j+(((double)i+1.0)*.003906250);
  1016.             ck= -.0078125*(double)j;
  1017.             parm1 = (double)x+.5+ci;
  1018.             parm2 = (double)y+.5+ck;
  1019.             break;
  1020.             }
  1021.             PRINTER_PRINTF5("PA %f,%f;PD;PR %f,%f;PU;\0",
  1022.             parm1,parm2, ci*((double)-2), ck*((double)-2));
  1023.           }
  1024.         }
  1025.           }
  1026.         }
  1027.         PRINTER_PRINTF3("%s;SC;PA 0,0;SP0;%s\0",EndOfLine,EndOfLine);
  1028.         PRINTER_PRINTF2(";;SP 0;%s\0",EndOfLine);
  1029.         break;
  1030.         }
  1031.     }
  1032.  
  1033.     if (Print_To_File > 0) fclose(PRFILE);
  1034. #ifndef XFRACT
  1035.     if ((LPTn==30)||(LPTn==31))
  1036.     {
  1037.     for (x=0;x<2000;x++);
  1038.     outp((LPTn==30) ? 0x3FC : 0x2FC,0x00);
  1039.     outp((LPTn==30) ? 0x3F9 : 0x2F9,0x00);
  1040.     }
  1041. #else
  1042.     putstring(5,0,0,"Printing done\n");
  1043. #endif
  1044. }
  1045.  
  1046.  
  1047. static void _fastcall graphics_init(int ptrid,int res,char *EndOfLine)
  1048. {
  1049.     int i,j;
  1050.  
  1051.     switch (ptrid) {
  1052.  
  1053.     case 1:
  1054.         print_title(ptrid,res,EndOfLine);
  1055.         PRINTER_PRINTF2("\033*t%iR\033*r0A",res);/* HP           */
  1056.         break;
  1057.  
  1058.     case 2:
  1059.     case 3:
  1060.         print_title(ptrid,res,EndOfLine);
  1061.         PRINTER_PRINTF1("\033\063\030");/* IBM                   */
  1062.         break;
  1063.  
  1064.     case 4: /****** PaintJet *****/
  1065.         print_title(ptrid,res,EndOfLine);
  1066.         pj_width = ydots;
  1067.         if (res == 90) pj_width <<= 1;
  1068.         PRINTER_PRINTF2("\033*r0B\033*t180R\033*r3U\033*r%dS\033*b0M\033*r0A",
  1069.         pj_width);
  1070.         pj_width >>= 3;
  1071.         break;
  1072.  
  1073.     case 5:   /***** PostScript *****/
  1074.     case 6:   /***** PostScript Landscape *****/
  1075.         if (!((EPSFileType > 0) && (ptrid==5)))
  1076.         PRINTER_PRINTF2("%%!PS-Adobe%s",EndOfLine);
  1077.         if ((EPSFileType > 0) &&     /* Only needed if saving to .EPS */
  1078.         (ptrid == 5))
  1079.         {
  1080.         PRINTER_PRINTF2("%%!PS-Adobe-1.0 EPSF-2.0%s",EndOfLine);
  1081.  
  1082.         if (EPSFileType==1)
  1083.             i=xdots+78;
  1084.         else
  1085.             i=(int)((double)xdots * (72.0 / (double)res))+78;
  1086.  
  1087.         if (Printer_Titleblock==0)
  1088.             {
  1089.             if (EPSFileType==1) { j = ydots + 78; }
  1090.             else { j = (int)(((double)ydots * (72.0 / (double)res) / (double)finalaspectratio)+78); }
  1091.             }
  1092.         else
  1093.             {
  1094.             if (EPSFileType==1) { j = ydots + 123; }
  1095.             else { j = (int)(((double)ydots * (72.0 / (double)res))+123); }
  1096.             }
  1097.         PRINTER_PRINTF4("%%%%TemplateBox: 12 12 %d %d%s",i,j,EndOfLine);
  1098.         PRINTER_PRINTF4("%%%%BoundingBox: 12 12 %d %d%s",i,j,EndOfLine);
  1099.         PRINTER_PRINTF4("%%%%PrinterRect: 12 12 %d %d%s",i,j,EndOfLine);
  1100.         PRINTER_PRINTF2("%%%%Creator: Fractint PostScript%s",EndOfLine);
  1101.         PRINTER_PRINTF5("%%%%Title: A %s fractal - %s - Fractint EPSF Type %d%s",
  1102.                        curfractalspecific->name[0]=='*' ?
  1103.                        &curfractalspecific->name[1] :
  1104.                        curfractalspecific->name,
  1105.                        PrintName,
  1106.                        EPSFileType,
  1107.                        EndOfLine);
  1108.         if (Printer_Titleblock==1)
  1109.             PRINTER_PRINTF2("%%%%DocumentFonts: Helvetica%s",EndOfLine);
  1110.         PRINTER_PRINTF2("%%%%EndComments%s",EndOfLine);
  1111.         PRINTER_PRINTF2("/EPSFsave save def%s",EndOfLine);
  1112.         PRINTER_PRINTF2("0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin%s",EndOfLine);
  1113.         PRINTER_PRINTF2("10 setmiterlimit [] 0 setdash newpath%s",EndOfLine);
  1114.         }
  1115.  
  1116.         /* Common code for all PostScript */
  1117.         PRINTER_PRINTF2("/Tr {translate} def%s",EndOfLine);
  1118.         PRINTER_PRINTF2("/Mv {moveto} def%s",EndOfLine);
  1119.         PRINTER_PRINTF2("/D {dup} def%s",EndOfLine);
  1120.         PRINTER_PRINTF2("/Rh {readhexstring} def%s",EndOfLine);
  1121.         PRINTER_PRINTF2("/Cf {currentfile} def%s",EndOfLine);
  1122.         PRINTER_PRINTF2("/Rs {readstring} def%s",EndOfLine);
  1123.  
  1124.         if (Printer_Compress) {
  1125.         rleprolog(xdots,ydots);
  1126.         } else 
  1127.         {
  1128.         PRINTER_PRINTF3("/picstr %d string def%s",
  1129.             ColorPS?xdots*3:xdots,EndOfLine);
  1130.         PRINTER_PRINTF7("/dopic { gsave %d %d 8 [%d 0 0 %d 0 %d]%s",
  1131.                      xdots, ydots, xdots, -ydots, ydots,
  1132.                      EndOfLine);
  1133.         PRINTER_PRINTF2("{ Cf picstr Rh pop }%s", EndOfLine);
  1134.         if (ColorPS)
  1135.         {
  1136.             PRINTER_PRINTF2(" false 3 colorimage grestore } def%s",
  1137.              EndOfLine);
  1138.         }
  1139.         else
  1140.         {
  1141.             PRINTER_PRINTF2(" image grestore } def%s", EndOfLine);
  1142.         }
  1143.             }
  1144.         if (Printer_Titleblock==1)
  1145.         {
  1146.         PRINTER_PRINTF2("/Helvetica findfont 8 scalefont setfont%s",EndOfLine);
  1147.         if (ptrid==5) {PRINTER_PRINTF1("30 60 Mv ");}
  1148.         else          {PRINTER_PRINTF1("552 30 Mv 90 rotate ");}
  1149.         print_title(ptrid,res,EndOfLine);
  1150.         if (ptrid==6) {PRINTER_PRINTF1("-90 rotate ");}
  1151.         }
  1152.  
  1153.         if (EPSFileType != 1) /* Do not use on a WELL BEHAVED .EPS */
  1154.           {
  1155.           if (ptrid == 5 && EPSFileType==2 
  1156.                          && (Printer_ColorXlat || Printer_SetScreen))
  1157.             PRINTER_PRINTF2("%%%%BeginFeature%s",EndOfLine);
  1158.           if (ColorPS)
  1159.         {
  1160.         if (Printer_ColorXlat==1)
  1161.             PRINTER_PRINTF2("{1 exch sub} D D D setcolortransfer%s",EndOfLine);
  1162.         if (Printer_ColorXlat>1)
  1163.             PRINTER_PRINTF4("{%d mul round %d div} D D D setcolortransfer%s",
  1164.                        Printer_ColorXlat,Printer_ColorXlat,EndOfLine);
  1165.         if (Printer_ColorXlat<-1)
  1166.             PRINTER_PRINTF4("{%d mul round %d div 1 exch sub} D D D setcolortransfer",
  1167.                        Printer_ColorXlat,Printer_ColorXlat,EndOfLine);
  1168.  
  1169.         if (Printer_SetScreen==1)
  1170.             {
  1171. #ifndef XFRACT            
  1172.             static char far fmt_str[] = "%d %d {%Fs}%s";
  1173. #else
  1174.             static char fmt_str[] = "%d %d {%s}%s";
  1175. #endif
  1176.             Printer_printf(fmt_str,
  1177.                        Printer_RFrequency,
  1178.                        Printer_RAngle,
  1179.                        (char far *)HalfTone[Printer_RStyle],
  1180.                        EndOfLine);
  1181.             Printer_printf(fmt_str,
  1182.                        Printer_GFrequency,
  1183.                        Printer_GAngle,
  1184.                        (char far *)HalfTone[Printer_GStyle],
  1185.                        EndOfLine);
  1186.             Printer_printf(fmt_str,
  1187.                        Printer_BFrequency,
  1188.                        Printer_BAngle,
  1189.                        (char far *)HalfTone[Printer_BStyle],
  1190.                        EndOfLine);
  1191.             Printer_printf(fmt_str,
  1192.                        Printer_SFrequency,
  1193.                        Printer_SAngle,
  1194.                        (char far *)HalfTone[Printer_SStyle],
  1195.                        EndOfLine);
  1196.             PRINTER_PRINTF2("setcolorscreen%s", EndOfLine);
  1197.             }
  1198.             }
  1199.           else
  1200.           {
  1201.          if (Printer_ColorXlat!=-2 && Printer_ColorXlat!=2) {
  1202.             /* b&w case requires no mask building */
  1203.            if (Printer_ColorXlat==1)
  1204.               PRINTER_PRINTF2("{1 exch sub} settransfer%s",EndOfLine);
  1205.            if (Printer_ColorXlat>1)
  1206.               PRINTER_PRINTF4("{%d mul round %d div} settransfer%s",
  1207.                       Printer_ColorXlat,Printer_ColorXlat,EndOfLine);
  1208.            if (Printer_ColorXlat<-1)
  1209.               PRINTER_PRINTF4("{%d mul round %d div 1 exch sub} settransfer",
  1210.                       Printer_ColorXlat,Printer_ColorXlat,EndOfLine);
  1211.         
  1212.            if (Printer_SetScreen==1)
  1213.                    {
  1214. #ifndef XFRACT           
  1215.               PRINTER_PRINTF5("%d %d {%Fs} setscreen%s",
  1216.                      Printer_SFrequency,
  1217.                      Printer_SAngle,
  1218.                      (char far *)HalfTone[Printer_SStyle],
  1219.                      EndOfLine);
  1220. #else
  1221.               Printer_printf("%d %d {%s} setscreen%s",
  1222.                      Printer_SFrequency,
  1223.                      Printer_SAngle,
  1224.                      (char far *)HalfTone[Printer_SStyle],
  1225.                      EndOfLine);
  1226. #endif
  1227.            }             
  1228.         }
  1229.           }
  1230.  
  1231.           if (ptrid == 5)
  1232.          {
  1233.             if ((EPSFileType==2) && (Printer_ColorXlat || Printer_SetScreen))
  1234.             PRINTER_PRINTF2("%%%%EndFeature%s",EndOfLine);
  1235.             if (res == 0)
  1236.             {
  1237.             PRINTER_PRINTF2("30 191.5 Tr 552 %4.1f",
  1238.                     (552.0*(double)finalaspectratio));
  1239.             }
  1240.             else
  1241.             {
  1242.             PRINTER_PRINTF4("30 %d Tr %f %f",
  1243.                      75 - ((Printer_Titleblock==1) ? 0 : 45),
  1244.                      ((double)xdots*(72.0/(double)res)),
  1245.                      ((double)xdots*(72.0/(double)res)*(double)finalaspectratio));
  1246.             }
  1247.           }
  1248.         else                 /* For Horizontal PostScript */
  1249.         {
  1250.             if (res == 0)
  1251.             {
  1252.             PRINTER_PRINTF2("582 30 Tr 90 rotate 732 %4.1f",
  1253.                     (732.0*(double)finalaspectratio));
  1254.             }
  1255.             else
  1256.             {
  1257.             PRINTER_PRINTF4("%d 30 Tr 90 rotate %f %f",
  1258.                      537 + ((Printer_Titleblock==1) ? 0 : 45),
  1259.                      ((double)xdots*(72.0/(double)res)),
  1260.                      ((double)xdots*(72.0/(double)res)*(double)finalaspectratio));
  1261.             }
  1262.         }
  1263.         PRINTER_PRINTF2(" scale%s",EndOfLine);
  1264.           }
  1265.  
  1266.         else if (ptrid == 5)       /* To be used on WELL-BEHAVED .EPS */
  1267.         PRINTER_PRINTF5("30 %d Tr %d %d scale%s",
  1268.                     75 - ((Printer_Titleblock==1) ? 0 : 45),
  1269.                     xdots,ydots,EndOfLine);
  1270.  
  1271.         PRINTER_PRINTF2("dopic%s",EndOfLine);
  1272.         break;
  1273.  
  1274.     case 7: /* HP Plotter */
  1275.         if (res<1) res=1;
  1276.         if (res>10) res=10;
  1277.         ci = (((double)xdots*((double)res-1.0))/2.0);
  1278.         ck = (((double)ydots*((double)res-1.0))/2.0);
  1279.         PRINTER_PRINTF6(";IN;SP0;SC%d,%d,%d,%d;%s\0",
  1280.         (int)(-ci),(int)((double)xdots+ci),
  1281.         (int)((double)ydots+ck),(int)(-ck),EndOfLine);
  1282.         break;
  1283.     }
  1284. }
  1285.  
  1286.  
  1287. static void _fastcall print_title(int ptrid,int res,char *EndOfLine)
  1288. {
  1289.     char buff[80];
  1290.     int postscript;
  1291.     if (Printer_Titleblock == 0)
  1292.     return;
  1293.     postscript = (ptrid == 5 || ptrid ==6);
  1294.     if (!postscript)
  1295.     Printer_printf(EndOfLine);
  1296.     else
  1297.     Printer_printf("(");
  1298.     Printer_printf((curfractalspecific->name[0]=='*')
  1299.              ? &curfractalspecific->name[1]
  1300.              : curfractalspecific->name);
  1301.     if (fractype == FORMULA || fractype == FFORMULA)
  1302.     Printer_printf(" %s",FormName);
  1303.     if (fractype == LSYSTEM)
  1304.     Printer_printf(" %s",LName);
  1305.     if (fractype == IFS || fractype == IFS3D)
  1306.     Printer_printf(" %s",IFSName);
  1307.     PRINTER_PRINTF4(" - %dx%d - %d DPI", xdots, ydots, res);
  1308.     if (!postscript)
  1309.     Printer_printf(EndOfLine);
  1310.     else {
  1311.     PRINTER_PRINTF2(") show%s",EndOfLine);
  1312.     if (ptrid==5) {PRINTER_PRINTF1("30 50 moveto (");}
  1313.     else          PRINTER_PRINTF1("-90 rotate 562 30 moveto 90 rotate (");
  1314.     }
  1315.     PRINTER_PRINTF5("Corners: Top-Left=%.16g/%.16g Bottom-Right=%.16g/%.16g",
  1316.            xxmin,yymax,xxmax,yymin);
  1317.     if (xx3rd != xxmin || yy3rd != yymin) {
  1318.     if (!postscript)
  1319.         Printer_printf("%s        ",EndOfLine);
  1320.     PRINTER_PRINTF3(" Bottom-Left=%4.4f/%4.4f",xx3rd,yy3rd);
  1321.     }
  1322.     if (!postscript)
  1323.     Printer_printf(EndOfLine);
  1324.     else {
  1325.     PRINTER_PRINTF2(") show%s",EndOfLine);
  1326.     if (ptrid==5) {PRINTER_PRINTF1("30 40 moveto (");}
  1327.     else          PRINTER_PRINTF1("-90 rotate 572 30 moveto 90 rotate (");
  1328.     }
  1329.     showtrig(buff);
  1330.     PRINTER_PRINTF6("Parameters: %4.4f/%4.4f/%4.4f/%4.4f %s",
  1331.            param[0],param[1],param[2],param[3],buff);
  1332.     if (!postscript)
  1333.     Printer_printf(EndOfLine);
  1334.     else
  1335.     PRINTER_PRINTF2(") show%s",EndOfLine);
  1336. }
  1337.  
  1338. /* This function prints a string to the the printer with BIOS calls. */
  1339.  
  1340. #ifndef XFRACT
  1341. static void Printer_printf(char far *fmt,...)
  1342. #else
  1343. static void Printer_printf(va_alist)
  1344. va_dcl
  1345. #endif
  1346. {
  1347. int i;
  1348. char s[500];
  1349. int x=0;
  1350. va_list arg;
  1351.  
  1352. #ifndef XFRACT
  1353. va_start(arg,fmt);
  1354. #else
  1355. char far *fmt;
  1356. va_start(arg);
  1357. fmt = va_arg(arg,char far *);
  1358. #endif
  1359.  
  1360. {
  1361.    /* copy far to near string */
  1362.    char fmt1[100];
  1363.    i=0;
  1364.    while(fmt[i]) {
  1365.      fmt1[i] = fmt[i];
  1366.      i++;
  1367.    }
  1368.    fmt1[i] = '\0';
  1369.    vsprintf(s,fmt1,arg);
  1370. }   
  1371.  
  1372. if (Print_To_File>0)    /* This is for printing to file */
  1373.     fprintf(PRFILE,"%s",s);
  1374. else            /* And this is for printing to printer */
  1375.     while (s[x])
  1376.     if (printer(s[x++]) != 0)
  1377.         while (!keypressed()) { if (printer(s[x-1])==0) break; }
  1378. }
  1379.  
  1380. /* This function standardizes both _bios_printer and _bios_serialcom
  1381.  * in one function.  It takes its arguments and rearranges them and calls
  1382.  * the appropriate bios call.  If it then returns result !=0, there is a
  1383.  * problem with the printer.
  1384.  */
  1385. static int _fastcall printer(int c)
  1386. {
  1387.     if (Print_To_File>0) return ((fprintf(PRFILE,"%c",c))<1);
  1388. #ifndef XFRACT
  1389.     if (LPTn<9)  return (((_bios_printer(0,LPTn,c))+0x0010)&0x0010);
  1390.     if (LPTn<19) return ((_bios_serialcom(1,(LPTn-10),c))&0x9E00);
  1391.     if ((LPTn==20)||(LPTn==21))
  1392.     {
  1393.     int PS=0;
  1394.     while ((PS & 0xF8) != 0xD8)
  1395.         { PS = inp((LPTn==20) ? 0x379 : 0x279);
  1396.           if (keypressed()) return(1); }
  1397.     outp((LPTn==20) ? 0x37C : 0x27C,c);
  1398.     PS = inp((LPTn==20) ? 0x37A : 0x27A);
  1399.     outp((LPTn==20) ? 0x37A : 0x27A,(PS | 0x01));
  1400.     outp((LPTn==20) ? 0x37A : 0x27A,PS);
  1401.     return(0);
  1402.     }
  1403.     if ((LPTn==30)||(LPTn==31))
  1404.     {
  1405.     while (((inp((LPTn==30) ? 0x3FE : 0x2FE)&0x30)!=0x30) ||
  1406.            ((inp((LPTn==30) ? 0x3FD : 0x2FD)&0x60)!=0x60))
  1407.         { if (keypressed()) return (1); }
  1408.     outp((LPTn==30) ? 0x3F8 : 0x2F8,c);
  1409.     return(0);
  1410.     }
  1411. #endif
  1412.  
  1413.     /* MCP 7-7-91, If we made it down to here, we may as well error out. */
  1414.     return(-1);
  1415. }
  1416.  
  1417. #ifdef __BORLANDC__
  1418. #if(__BORLANDC__ > 2)
  1419.    #pragma warn +eff
  1420. #endif
  1421. #endif
  1422.  
  1423. static void printer_reset(void)
  1424. {
  1425. #ifndef XFRACT
  1426.     if (Print_To_File < 1)
  1427.     if (LPTn<9)      _bios_printer(1,LPTn,0);
  1428.     else if (LPTn<19) _bios_serialcom(3,(LPTn-10),0);
  1429. #endif
  1430. }
  1431.  
  1432.  
  1433. /** debug code for pj_ color table checkout
  1434. color_test()
  1435. {
  1436.    int x,y,color,i,j,xx,yy;
  1437.    int bw,cw,bh,ch;
  1438.    setvideomode(videoentry.videomodeax,
  1439.         videoentry.videomodebx,
  1440.         videoentry.videomodecx,
  1441.         videoentry.videomodedx);
  1442.    bw = xdots/25; cw = bw * 2 / 3;
  1443.    bh = ydots/10; ch = bh * 2 / 3;
  1444.    dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 60;
  1445.    if (debugflag == 902)
  1446.       dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  1447.    for (x = 0; x < 25; ++x)
  1448.       for (y = 0; y < 10; ++y) {
  1449.      if (x < 11) i = (32 - x) * 10 + y;
  1450.          else    i = (24 - x) * 10 + y;
  1451.      color = x * 10 + y + 1;
  1452.      dacbox[color][0] = triple[0][0][i];
  1453.      dacbox[color][1] = triple[0][1][i];
  1454.      dacbox[color][2] = triple[0][2][i];
  1455.      for (i = 0; i < cw; ++i) {
  1456.         xx = x * bw + bw / 6 + i;
  1457.         yy = y * bh + bh / 6;
  1458.         for (j = 0; j < ch; ++j)
  1459.            putcolor(xx,yy++,color);
  1460.         }
  1461.      }
  1462.    spindac(0,1);
  1463.    getakey();
  1464. }
  1465. **/
  1466.  
  1467.  
  1468. /*
  1469.  * The following code for compressed PostScript is based on pnmtops.c.  It is
  1470.  * copyright (C) 1989 by Jef Poskanzer, and carries the following notice:
  1471.  * "Permission to use, copy, modify, and distribute this software and its
  1472.  *  documentation for any purpose and without fee is hereby granted, provided
  1473.  *  that the above copyright notice appear in all copies and that both that
  1474.  *  copyright notice and this permission notice appear in supporting
  1475.  *  documentation.  This software is provided "as is" without express or
  1476.  *  implied warranty."
  1477.  */
  1478.  
  1479.  
  1480. static void rleprolog(int x,int y)
  1481. {
  1482.     itemsperline = 0;
  1483.     items = 0;
  1484.     bitspersample = 8;
  1485.     repeat = 1;
  1486.     rlebitsperitem = 0;
  1487.     rlebitshift = 0;
  1488.     count = 0;
  1489.  
  1490.     PRINTER_PRINTF2( "/rlestr1 1 string def%s", EndOfLine );
  1491.     PRINTER_PRINTF2( "/rdrlestr {%s", EndOfLine );    /* s -- nr */
  1492.     PRINTER_PRINTF2( "  /rlestr exch def%s", EndOfLine );    /* - */
  1493.     PRINTER_PRINTF2( "  Cf rlestr1 Rh pop%s", EndOfLine );  /* s1 */
  1494.     PRINTER_PRINTF2( "  0 get%s", EndOfLine );                     /* c */
  1495.     PRINTER_PRINTF2( "  D 127 le {%s", EndOfLine );         /* c */
  1496.     PRINTER_PRINTF2( "    Cf rlestr 0%s", EndOfLine );      /* c f s 0 */
  1497.     PRINTER_PRINTF2( "    4 3 roll%s", EndOfLine );                /* f s 0 c */
  1498.     PRINTER_PRINTF2( "    1 add  getinterval%s", EndOfLine );      /* f s */
  1499.     PRINTER_PRINTF2( "    Rh pop%s", EndOfLine );    /* s */
  1500.     PRINTER_PRINTF2( "    length%s", EndOfLine );                  /* nr */
  1501.     PRINTER_PRINTF2( "  } {%s", EndOfLine );                       /* c */
  1502.     PRINTER_PRINTF2( "    256 exch sub D%s", EndOfLine );     /* n n */
  1503.     PRINTER_PRINTF2( "    Cf rlestr1 Rh pop%s", EndOfLine );/* n n s1 */
  1504.     PRINTER_PRINTF2( "    0 get%s", EndOfLine );                   /* n n c */
  1505.     PRINTER_PRINTF2( "    exch 0 exch 1 exch 1 sub {%s", EndOfLine );           /* n c 0 1 n-1*/
  1506.     PRINTER_PRINTF2( "      rlestr exch 2 index put%s", EndOfLine );
  1507.     PRINTER_PRINTF2( "    } for%s", EndOfLine );                   /* n c */
  1508.     PRINTER_PRINTF2( "    pop%s", EndOfLine );                     /* nr */
  1509.     PRINTER_PRINTF2( "  } ifelse%s", EndOfLine );                  /* nr */
  1510.     PRINTER_PRINTF2( "} bind def%s", EndOfLine );
  1511.     PRINTER_PRINTF2( "/Rs {%s", EndOfLine );           /* s -- s */
  1512.     PRINTER_PRINTF2( "  D length 0 {%s", EndOfLine );         /* s l 0 */
  1513.     PRINTER_PRINTF2( "    3 copy exch%s", EndOfLine );          /* s l n s n l*/
  1514.     PRINTER_PRINTF2( "    1 index sub%s", EndOfLine );          /* s l n s n r*/
  1515.     PRINTER_PRINTF2( "    getinterval%s", EndOfLine );          /* s l n ss */
  1516.     PRINTER_PRINTF2( "    rdrlestr%s", EndOfLine );       /* s l n nr */
  1517.     PRINTER_PRINTF2( "    add%s", EndOfLine );                     /* s l n */
  1518.     PRINTER_PRINTF2( "    2 copy le { exit } if%s", EndOfLine );   /* s l n */
  1519.     PRINTER_PRINTF2( "  } loop%s", EndOfLine );                    /* s l l */
  1520.     PRINTER_PRINTF2( "  pop pop%s", EndOfLine );                   /* s */
  1521.     PRINTER_PRINTF2( "} bind def%s", EndOfLine );
  1522.     if (ColorPS) {
  1523.     PRINTER_PRINTF3( "/rpicstr %d string def%s", x,EndOfLine );
  1524.     PRINTER_PRINTF3( "/gpicstr %d string def%s", x,EndOfLine );
  1525.     PRINTER_PRINTF3( "/bpicstr %d string def%s", x,EndOfLine );
  1526.     } else {
  1527.     PRINTER_PRINTF3( "/picstr %d string def%s", x,EndOfLine );
  1528.     }
  1529.     PRINTER_PRINTF2( "/dopic {%s", EndOfLine);
  1530.     PRINTER_PRINTF2( "/gsave%s", EndOfLine);
  1531.     if (ColorPS) {
  1532.        PRINTER_PRINTF4( "%d %d 8%s", x, y, EndOfLine);
  1533.     } else { /* b&w */
  1534.        if (Printer_ColorXlat==-2) {
  1535.           PRINTER_PRINTF4( "%d %d true%s", x, y, EndOfLine);
  1536.        } else if (Printer_ColorXlat==2) {
  1537.           PRINTER_PRINTF4( "%d %d false%s", x, y, EndOfLine);
  1538.        } else {
  1539.       PRINTER_PRINTF4( "%d %d 8%s", x, y, EndOfLine);
  1540.        }
  1541.     }
  1542.     PRINTER_PRINTF5( "[%d 0 0 %d 0 %d]%s", x, -y, y, EndOfLine);
  1543.     if (ColorPS) {
  1544.     PRINTER_PRINTF2( "{rpicstr Rs}%s", EndOfLine);
  1545.     PRINTER_PRINTF2( "{gpicstr Rs}%s", EndOfLine);
  1546.     PRINTER_PRINTF2( "{bpicstr Rs}%s", EndOfLine);
  1547.     PRINTER_PRINTF2( "true 3 colorimage%s", EndOfLine);
  1548.     } else {
  1549.        if (Printer_ColorXlat==-2 || Printer_ColorXlat==2) {
  1550.       /* save file space and printing time (if scaling is right) */
  1551.       PRINTER_PRINTF2( "{picstr Rs} imagemask%s", EndOfLine);
  1552.        } else {
  1553.       PRINTER_PRINTF2( "{picstr Rs} image%s", EndOfLine);
  1554.        }
  1555.     }
  1556.     PRINTER_PRINTF2( "} def%s", EndOfLine);
  1557. }
  1558.  
  1559. static void
  1560. rleputbuffer(void)
  1561.     {
  1562.     int i;
  1563.  
  1564.     if ( repeat )
  1565.     {
  1566.     item = 256 - count;
  1567.     putitem();
  1568.     item = repeatitem;
  1569.     putitem();
  1570.     }
  1571.     else
  1572.     {
  1573.     item = count - 1;
  1574.     putitem();
  1575.     for ( i = 0; i < count; ++i )
  1576.         {
  1577.         item = itembuf[i];
  1578.         putitem();
  1579.         }
  1580.     }
  1581.     repeat = 1;
  1582.     count = 0;
  1583.     }
  1584.  
  1585. static void
  1586. rleputitem(void)
  1587.     {
  1588.     int i;
  1589.  
  1590.     if ( count == 128 )
  1591.     rleputbuffer();
  1592.  
  1593.     if ( repeat && count == 0 )
  1594.     { /* Still initializing a repeat buf. */
  1595.     itembuf[count] = repeatitem = rleitem;
  1596.     ++count;
  1597.     }
  1598.     else if ( repeat )
  1599.     { /* Repeating - watch for end of run. */
  1600.     if ( rleitem == repeatitem )
  1601.         { /* Run continues. */
  1602.         itembuf[count] = rleitem;
  1603.         ++count;
  1604.         }
  1605.     else
  1606.         { /* Run ended - is it long enough to dump? */
  1607.         if ( count > 2 )
  1608.         { /* Yes, dump a repeat-mode buffer and start a new one. */
  1609.         rleputbuffer();
  1610.         itembuf[count] = repeatitem = rleitem;
  1611.         ++count;
  1612.         }
  1613.         else
  1614.         { /* Not long enough - convert to non-repeat mode. */
  1615.         repeat = 0;
  1616.         itembuf[count] = repeatitem = rleitem;
  1617.         ++count;
  1618.         repeatcount = 1;
  1619.         }
  1620.         }
  1621.     }
  1622.     else
  1623.     { /* Not repeating - watch for a run worth repeating. */
  1624.     if ( rleitem == repeatitem )
  1625.         { /* Possible run continues. */
  1626.         ++repeatcount;
  1627.         if ( repeatcount > 3 )
  1628.         { /* Long enough - dump non-repeat part and start repeat. */
  1629.         count = count - ( repeatcount - 1 );
  1630.         rleputbuffer();
  1631.         count = repeatcount;
  1632.         for ( i = 0; i < count; ++i )
  1633.             itembuf[i] = rleitem;
  1634.         }
  1635.         else
  1636.         { /* Not long enough yet - continue as non-repeat buf. */
  1637.         itembuf[count] = rleitem;
  1638.         ++count;
  1639.         }
  1640.         }
  1641.     else
  1642.         { /* Broken run. */
  1643.         itembuf[count] = repeatitem = rleitem;
  1644.         ++count;
  1645.         repeatcount = 1;
  1646.         }
  1647.     }
  1648.  
  1649.     rleitem = 0;
  1650.     rlebitsperitem = 0;
  1651.     }
  1652.  
  1653. static void 
  1654. putitem (void)
  1655.     {
  1656.     char* hexits = "0123456789abcdef";
  1657.  
  1658.     if ( itemsperline == 30 )
  1659.         {
  1660.     Printer_printf("%s",EndOfLine);
  1661.         itemsperline = 0;
  1662.         }
  1663.     Printer_printf("%c%c", hexits[item >> 4], hexits[item & 15] );
  1664.     ++itemsperline;
  1665.     ++items;
  1666.     item = 0;
  1667.     /* bitsperitem = 0; */
  1668.     bitshift2 = 8 - bitspersample;
  1669.     }
  1670.  
  1671. static void
  1672. rleputxelval( int xv )
  1673.     {
  1674.     if ( rlebitsperitem == 8 )
  1675.     rleputitem();
  1676.     rleitem += xv<<bitshift2;
  1677.     rlebitsperitem += bitspersample;
  1678.     rlebitshift -= bitspersample;
  1679.     }
  1680.  
  1681. static void
  1682. rleflush(void)
  1683.     {
  1684.     if ( rlebitsperitem > 0 )
  1685.     rleputitem();
  1686.     if ( count > 0 )
  1687.     rleputbuffer();
  1688.     }
  1689.  
  1690. static void
  1691. rleputrest(void)
  1692.     {
  1693.     rleflush();
  1694.     Printer_printf( "%s",EndOfLine );
  1695.     Printer_printf( "grestore%s",EndOfLine );
  1696.     }
  1697.